﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ShareIt_MVC3.Models;

namespace ShareIt_MVC3.Tests
{
    /// <summary>
    /// Summary description for UnitTestLending
    /// </summary>
    [TestClass]
    public class UnitTestLending
    {
        public UnitTestLending()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }


        [TestInitialize]
        public void Initialize()
        {
            // Datenbank leeren!
            Utilities.EmptyDB();
        }


        /// <summary>
        /// Test: Read all Lendings, insert one, search it in list, delete it again
        /// </summary>
        [TestMethod]
        public void TestInsertDeleteLending()
        {
            int i, c1, c2, c3;
            Console.WriteLine("TestInsertDeleteLending(): Start");
            List<Lending> LendingList;
            LendingCollection lendColl = new LendingCollection();
            ResourceCollection resColl = new ResourceCollection();
            UserCollection userColl = new UserCollection();
            User testUser = new User()
            {
                Username = "TestUsername",
                Name = "TestName",
                Surname = "TestSurname",
                Address = "TestAddress",
                City = "TestCity",
                ZIP = "12345",
                EMail = "test@test.de",
                IsAdmin = false,
                Active = true,
                Password = "TestPassword",
                Credits = 1
            };

            userColl.InsertUser(testUser);

            Resource testResource = new Resource()
            {
                Active = true,
                Author = "TestAutor",
                Category = "TestCategory",
                Owner = userColl.GetUserByUsername("TestUsername"),
                Title = "TestTitle"
            };

            resColl.InsertResource(testResource);

            Lending testLending = new Lending
            {
                DateOfLending = "01.01.1960",
                DateOfReturning = "01.02.1960",
                Lender = userColl.GetUserByUsername(testUser.Username),
                Resource = resColl.GetAllResources()[0],
            };

            // read Lending list
            LendingList = lendColl.GetAllLendings();
            c1 = LendingList.Count;
            // insert new Lending object
            i = lendColl.InsertLending(testLending);
            Assert.AreEqual(i, 1, "Insert failed");
            Console.WriteLine("TestInsertDeleteLending(): Insert");

            // read Lending list again and check if there is one more in list
            LendingList = lendColl.GetAllLendings();
            c2 = LendingList.Count;
            Assert.AreEqual(c1 + 1, c2);
            // look for Lending object that was just inserted and delete it again
            foreach (Lending p in LendingList)
            {   
                if (p.DateOfLending == "01.01.1960 00:00:00")
                {
                    i = lendColl.DeleteLending(p);
                    Assert.AreEqual(i, 1, "delete Failed!");
                    Console.WriteLine("TestInsertDeleteLending(): Delete");
                }
            }
            // read Lending list again and check if there is one less in list
            LendingList = lendColl.GetAllLendings();
            c3 = LendingList.Count;
            Assert.AreEqual(c1, c3, "Count after Delete wrong!");
            Console.WriteLine("TestInsertDeleteLending(): End");
        }


        /// <summary>
        /// Test: Read all Lendings, insert one, update it, delete it again
        /// </summary>
        [TestMethod]
        public void TestInsertUpdateDeleteLending()
        {
            int i, c1, c2, c3, pid;
            List<Lending> LendingList;
            LendingCollection lendColl = new LendingCollection();
            ResourceCollection resColl = new ResourceCollection();
            UserCollection userColl = new UserCollection();
            User testUser = new User()
            {
                Username = "TestUsername",
                Name = "TestName",
                Surname = "TestSurname",
                Address = "TestAddress",
                City = "TestCity",
                ZIP = "12345",
                EMail = "test@test.de",
                IsAdmin = false,
                Active = true,
                Password = "TestPassword",
                Credits = 1
            };

            userColl.InsertUser(testUser);

            Resource testResource = new Resource()
            {
                Active = true,
                Author = "TestAutor",
                Category = "TestCategory",
                Owner = userColl.GetUserByUsername("TestUsername"),
                Title = "TestTitle"
            };

            resColl.InsertResource(testResource);

            Lending testLending = new Lending
            {
                DateOfLending = "01.01.1960",
                DateOfReturning = "01.02.1960",
                Lender = userColl.GetUserByUsername(testUser.Username),
                Resource = resColl.GetAllResources()[0],
            };

            LendingList = lendColl.GetAllLendings();
            c1 = LendingList.Count;
            i = lendColl.InsertLending(testLending);
            Assert.AreEqual(i, 1);
            LendingList = lendColl.GetAllLendings();
            c2 = LendingList.Count;
            Assert.AreEqual(c1 + 1, c2);
            foreach (Lending p in LendingList)
            {
                if (p.DateOfLending == "01.01.1960 00:00:00")
                {
                    pid = p.ID;
                    p.DateOfReturning = "01.01.1970 00:00:00";
                    i = lendColl.UpdateLending(p);
                    Assert.AreEqual(i, 1);
                    testLending = lendColl.GetLendingById(pid);
                    Assert.AreEqual(testLending.DateOfLending, "01.01.1960 00:00:00");
                    Assert.AreEqual(testLending.DateOfReturning, "01.01.1970 00:00:00");
                    i = lendColl.DeleteLending(testLending);
                    Assert.AreEqual(i, 1);
                }
            }

            LendingList = lendColl.GetAllLendings();
            c3 = LendingList.Count;
            Assert.AreEqual(c1, c3);

        }

        
        /// <summary>
        /// test: try to delete non-existent Lending
        /// </summary>
        [TestMethod]
        public void TestDeleteNonExistentLending()
        {
            int i, c1, c2, c3;
            List<Lending> LendingList;

            Console.WriteLine("TestDeleteNonExistentLending(): Start");
            LendingCollection Lendings = new LendingCollection();
            Lending testLending = new Lending();
            testLending.DateOfLending = "01.01.1960 00:00:00";
            testLending.DateOfReturning = "01.01.1960 00:00:00";


            LendingList = Lendings.GetAllLendings();
            c1 = LendingList.Count;
            foreach (Lending p in LendingList)
            {
                if (p.DateOfLending == "01.01.1960 00:00:00")
                {
                    Assert.Inconclusive("TestDeleteNonExistentLending(): Lending with StartDate 01.01.1960 exists already???");
                }
            }
            i = Lendings.DeleteLending(testLending);
            Assert.AreEqual(0, i, "TestDeleteNonExistentLending(): DeleteLending unexpected result");
            LendingList = Lendings.GetAllLendings();
            c3 = LendingList.Count;
            Assert.AreEqual(c1, c3, "TestDeleteNonExistentLending(): Count after Delete wrong!");
            Console.WriteLine("TestDeleteNonExistentLending(): End");

        }

        /*
        /// <summary>
        /// try to update non-existent Lending
        /// </summary>
        [TestMethod]
        public void TestUpdateNonExistentLending()
        {
            int i, c1, c2, c3;
            List<Lending> LendingList;

            Console.WriteLine("TestUpdateNonExistentLending(): Start");
            LendingCollection Lendings = new LendingCollection();
            Lending testLending = new Lending()
            {
                Lendingname = "TestLendingname",
                Name = "TestName",
                Surname = "TestSurname",
                Address = "TestAddress",
                City = "TestCity",
                ZIP = "12345",
                EMail = "test@test.de",
                IsAdmin = false,
                Active = true,
                Password = "TestPassword",
                Credits = 1
            };

            LendingList = Lendings.GetAllLendings();
            c1 = LendingList.Count;
            i = Lendings.UpdateLending(testLending);
            Assert.AreEqual(0, i, "TestUpdateNonExistentLending(): Update unexpected result");
            Console.WriteLine("TestDeleteNonExistentLending(): End");
        }

        [TestMethod]
        public void TestIncrementLendingCredits()
        {
            LendingCollection LendingColl = new LendingCollection();
            Lending testLending = new Lending()
            {
                Lendingname = "TestLendingname",
                Name = "TestName",
                Surname = "TestSurname",
                Address = "TestAddress",
                City = "TestCity",
                ZIP = "12345",
                EMail = "test@test.de",
                IsAdmin = false,
                Active = true,
                Password = "TestPassword",
                Credits = 1
            };
            int i = LendingColl.InsertLending(testLending);
            Assert.AreEqual(1, i);

            Lending Lending = LendingColl.GetLendingByLendingname(testLending.Lendingname);
            int currentCredits = Lending.Credits;

            int c = LendingColl.IncrementLendingCredits(Lending);
            Assert.AreEqual(1, c);

            Lending = LendingColl.GetLendingByLendingname(testLending.Lendingname);
            Assert.AreEqual(currentCredits + 1, Lending.Credits);

            // Lending cleanup
            LendingColl.DeleteLending(LendingColl.GetLendingByLendingname(testLending.Lendingname));


        }

        [TestMethod]
        public void TestDecrementLendingCredits()
        {
            LendingCollection LendingColl = new LendingCollection();
            Lending testLending = new Lending()
            {
                Lendingname = "TestLendingname",
                Name = "TestName",
                Surname = "TestSurname",
                Address = "TestAddress",
                City = "TestCity",
                ZIP = "12345",
                EMail = "test@test.de",
                IsAdmin = false,
                Active = true,
                Password = "TestPassword",
                Credits = 1
            };

            int i = LendingColl.InsertLending(testLending);
            Assert.AreEqual(1, i);

            Lending Lending = LendingColl.GetLendingByLendingname(testLending.Lendingname);
            int currentCredits = Lending.Credits;

            int c = LendingColl.DecrementLendingCredits(Lending);
            Assert.AreEqual(1, c);

            Lending = LendingColl.GetLendingByLendingname(testLending.Lendingname);
            Assert.AreEqual(currentCredits - 1, Lending.Credits);

            // Lending cleanup
            LendingColl.DeleteLending(LendingColl.GetLendingByLendingname(testLending.Lendingname));


        }
         */
    }
}
